﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace org.alex.edss
{
    public class Session:IResetObject
    {

        public event SessionEventHandler OnReading;

        public event SessionEventHandler ReadComplete;

        public event SessionEventHandler SendComplete;

        public event SessionEventHandler SessionEnd;

        public event ErrorEventHandler SessionError;

        public int Key
        {
            get;
            set;
        }

        public Byte[] ReadBuffer
        {
            get;
            set;
        }

        public Connector Connection
        {
            get;
            set;
        }

        public Hashtable UserData
        {
            get;
            set;
        }

        public SocketAsyncEventArgs ReadArgs
        {
            get;
            set;
        }

        public SocketAsyncEventArgs WriteArgs
        {
            get;
            set;
        }

        public EdsServer Server
        {
            get;
            set;
        }

        private bool working = false;

        public Session(int BufferSize)
        {
            try
            {
                working = true;
                ReadBuffer = new Byte[BufferSize];
                UserData = new Hashtable();
                ReadArgs = new SocketAsyncEventArgs();
                //ReadArgs.Completed += new EventHandler<SocketAsyncEventArgs>(ReadArg_Completed);
                ReadArgs.SetBuffer(ReadBuffer, 0, BufferSize);
                WriteArgs = new SocketAsyncEventArgs();
                //WriteArgs.Completed += new EventHandler<SocketAsyncEventArgs>(WriteArgs_Completed);
            }
            catch (Exception ex)
            {
                if (SessionError != null)
                {
                    SessionError(this, ex);
                }
            }
        }

        public void Start(Socket AcceptSock,EdsServer BaseServer)
        {
            try
            {
                this.Server = BaseServer;
                Connection = new Connector(AcceptSock, ReadArgs, WriteArgs, ReadBuffer);
                Connection.OperationError += new ConnectionEventHandler(Connection_OperationError);
                Connection.OnRead += new ConnectionEventHandler(Connection_OnRead);
                Connection.ReadComplete += new ConnectionEventHandler(Connection_ReadComplete);
                Connection.WriteComplete += new ConnectionEventHandler(Connection_WriteComplete);
                ReadArgs.UserToken = this;
            }
            catch (Exception ex)
            {
                if (SessionError != null)
                {
                    SessionError(this, 0);
                }
            }
        }

        void Connection_WriteComplete(Connector Sender, object Args)
        {
            //throw new NotImplementedException();
            if (SendComplete != null)
            {
                SendComplete(this, 0);
            }

        }

        void Connection_ReadComplete(Connector Sender, object Args)
        {
            //throw new NotImplementedException();
            if (ReadComplete != null)
            {
                ReadComplete(this, Sender.Offset);
            }
        }

        void Connection_OnRead(Connector Sender, object Args)
        {
            //throw new NotImplementedException();
            if (OnReading != null)
            {
                OnReading(this, Sender.Offset);
            }
        }

        void Connection_OperationError(Connector Sender, object Args)
        {
            //throw new NotImplementedException();
            if (SessionError != null)
            {
                SessionError(this, Args);
                try
                {
                    Close();
                }
                catch { }
            }
        }

        public void SetError()
        {
            if (SessionError != null)
            {
                SessionError(this, "err happen");
            }
        }

        public void Close()
        {
            try
            {
                if (working)
                {
                    Connection.Disconnect();
                    if (SessionEnd != null)
                    {
                        SessionEnd(this, 0);
                    }
                    Server.Sessions.ReleaseSession(Key);
                }
                working = false;
            }
            catch (Exception ex)
            {
                working = false;
                if (SessionError != null)
                {
                    SessionError(this, ex);
                }

            }
        }

        #region IResetObject 成员

        public void Reset()
        {
            try
            {
                //throw new NotImplementedException();
                Key = 0;
                ReadBuffer = new byte[ReadBuffer.Length];
                UserData.Clear();
            }
            catch (Exception ex)
            {
                if (SessionError != null)
                {
                    SessionError(this, ex);
                }
            }
        }

        #endregion

    }
}
